R语言系列第五期:③R语言逻辑回归预测和检验

您所在的位置:网站首页 r语言 logistic预测模型 R语言系列第五期:③R语言逻辑回归预测和检验

R语言系列第五期:③R语言逻辑回归预测和检验

2024-07-12 02:28| 来源: 网络整理| 查看: 265

在上一篇文章里,无论原始数据是表格式的还是罗列式的,我们都可以建立起相应的逻辑回归模型。详情点击:R语言系列五:②R语言与逻辑回归建立

但是模型建立起来之后,是用来做什么的?我们当然需要利用模型来解释变量,但是我们也可以利用模型来预测结局,我们建立起来模型之后,可以通过个人的数据来计算这个人发生阳性事件的概率大小,从而最终给出结局分类,并且做出相应的对策。

我们首先考虑之前的高血压的例子,这个例子中共有8个分类组合的水平,我们为了方便后续的操作,我们把上一节的表列在这里:

smoking obesity snoring n.tot n.hyp

1 No No No 60 5

2 Yes No No 17 2

3 No Yes No 8 1

4 Yes Yes No 2 0

5 No No Yes 187 35

6 Yes No Yes 85 13

7 No Yes Yes 51 15

8 Yes Yes Yes 23 8

我们接着上一部分的内容,把smoking变量给删除掉重新建立模型,而我们做预测的函数就是predict(),我们得到的预测结果是以列表的形式给出:

> glm.hyp=glm(hyp.tbl~obesity+snoring,family=binomial("logit"))

Call: glm(formula = hyp.tbl ~ obesity + snoring, family = binomial("logit"))

Coefficients:

(Intercept) obesityYes snoringYes

-2.3921 0.6954 0.8655

Degrees of Freedom: 7 Total (i.e. Null); 5 Residual

Null Deviance: 14.13

Residual Deviance: 1.678 AIC: 32.6

> summary(glm.hyp)

Call:

glm(formula = hyp.tbl ~ obesity + snoring, family = binomial("logit"))

Deviance Residuals:

1 2 3 4 5 6 7 8

-0.01247 0.47756 -0.24050 -0.82050 0.30794 -0.62742 -0.14449 0.45770

Coefficients:

Estimate Std. Error z value Pr(>|z|)

(Intercept) -2.3921 0.3757 -6.366 1.94e-10 ***

obesityYes 0.6954 0.2851 2.440 0.0147 *

snoringYes 0.8655 0.3967 2.182 0.0291 *

---

Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

Null deviance: 14.1259 on 7 degrees of freedom

Residual deviance: 1.6781 on 5 degrees of freedom

AIC: 32.597

Number of Fisher Scoring iterations: 4

> predict(glm.hyp)

1 2 3 4

-2.3920763 -2.3920763 -1.6966575 -1.6966575

5 6 7 8

-1.5266180 -1.5266180 -0.8311991 -0.8311991

#Tips:当前代码是在上一节的内容的基础上进行的!

#Tips:首先,我们删掉了smoking变量之后,剩下的两个变量都是有统计学意义的变量。而删掉了smoking之后,预测的结果就是两两相等的。另外这些值都是在logit刻度下的,所以我们再去计算这个公式里P值解之后就可以得到阳性率。比如第一个数值,-2.3920763,我们由下面公式计算得到P值是0.08378.

#Tips:另一件事是,你会发现2.392-1.697=1.527-0.831=0.695(四舍五入的误差不考虑),这个值是obesity的回归系数,而snoring的回归系数则为2.392-1.527=1.697-0.831=0.866。

当然,我们也可以直接显示概率刻度下的预测值,需要在predict函数中设定参数type=“response”:

> predict(glm.hyp,type="response")

1 2 3 4

0.08377892 0.08377892 0.15490233 0.15490233

5 6 7 8

0.17848906 0.17848906 0.30339158 0.30339158

另一种情况,连续型自变量里,比如menarche的分析中,我们可以给每个点都计算概率,但是对于我们而言没有什么意义,我们的主要兴趣点在于看到年龄和期望概率的关系图。我们可以用如下代码画一下:

> glm.menarche Age newages predicted.probability plot(predicted.probability~Age,type="l")

#Tips:Age变量是用来做横轴的点,seq()函数生成等距元素的向量,这里年龄是从8-20岁,间隔为0.1,所以点连起来会很光滑。predicted.probability可以通过我们第一行代码建立的回归模型,计算Age变量所对应的每个点的概率值,这样我们每个x,y都计算出来之后,使用plot()函数就可以把他们绘制出来了。

B. 模型检查

当然,我们建立了模型之后,肯定要利用模型说明问题,但是我们建立的模型到底好不好,我们又必须给出适当的判断。

对于表格式的数据,很明显,我们应该去比较观测和拟合出来的值的占比。在前面高血压的例子中,我们可以计算各组水平概率(下面的是实际概率):

> fitted(glm.hyp)

1 2 3 4

0.08377892 0.08377892 0.15490233 0.15490233

5 6 7 8

0.17848906 0.17848906 0.30339158 0.30339158

#Tips:fitted()函数是用来计算利用原建模数据和已建成模型所得最终预测值的函数。fitted()函数和predict()函数很类似,但是它不可以利用外部数据计算新的概率。下面是实际的对应阳性事件发生率。

> prop.hyp

[1] 0.08333333 0.11764706 0.12500000 0.00000000

[5] 0.18716578 0.15294118 0.29411765 0.34782609

问题在于,你不知道相对频率是如何计算得到的,如果能看一看观测到的频数和,估计得到的数量会更好一些:

> fitted(glm.hyp)*n.tot

1 2 3 4

5.0267351 1.4242416 1.2392186 0.3098047

5 6 7 8

33.3774535 15.1715698 15.4729705 6.9780063

我们可以把比较的内容以更好的方式打印出来:

> data.frame(fit=fitted(glm.hyp)*n.tot,n.hyp,n.tot)

fit n.hyp n.tot

1 5.0267351 5 60

2 1.4242416 2 17

3 1.2392186 1 8

4 0.3098047 0 2

5 33.3774535 35 187

6 15.1715698 13 85

7 15.4729705 15 51

8 6.9780063 8 23

#Tips:第四个观测,出现15%的期望和0%的观测这样的差别,虽然差别大,但是模型预测里只有0.3个高血压,而实际是0个,所以要注意相对数使用时容易出现这样的问题。

对于连续多变量的复杂模型,对其进行充分的检查是蛮困难的。当观测数据只有两个不同的取值时,就没有方法利用残差图进行检验了。

我们利用menarche的例子。我们试着将x轴划分为几个区间,然后看看每个区间里的点的数量占比与估计的概率之间是否相符:

> age.group tb tb

menarche

age.group No Yes

(8,10] 100 0

(10,12] 97 4

(12,13] 32 21

(13,14] 22 20

(14,15] 5 36

(15,16] 0 31

(16,18] 0 105

(18,20] 0 46

> rel.freq rel.freq

(8,10] (10,12] (12,13] (13,14]

0.00000000 0.03960396 0.39622642 0.47619048

(14,15] (15,16] (16,18] (18,20]

0.87804878 1.00000000 1.00000000 1.00000000

> points(rel.freq~c(9,11,12.5,13.5,14.5,15.5,17,19),pch=5)

#Tips:我们需要对上面所用到的方法进行解释,首先,cut()函数用于定义因子age.group,它把原来的连续性数据划分成多个组,有点像factor()函数,但是它会给出明确的分割点,而factor()是原先就分好的类。cut()的第二个参数就是分割点;然后table()函数利用age.table变量和menarche变量进行制表。使用prop.table()函数,我们之前提过,它会计算tb表格中每行行内数据构成比(1表示行,2表示列),随后[,2]表示只保留第二列,即yes的那一列;最后,绘制关于期望概率的图,与观测占比的图叠加起来。我们是在原先的图的基础上把点给叠加上去的。pch参数表示使用什么符号,5代表菱形。

整体来看,这个图还是有意义的,尽管12-13岁年龄段和13-14年龄段原始数据和预测数据略有差池。

但是这样的偏差是否有统计学意义呢?其实这个方法并不能非常好的给出结果,我们只能直观的感觉预测效果如何而异。

这里推荐使用一个检验模型很好的工具ROC曲线,我们可以一步一步告诉你ROC曲线是如何画出来的:

> glm.menarche pre pre.obs pre.obs n tpr



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3